package utils;

import java.awt.Color;
import java.awt.image.BufferedImage;

import structs.Vector2;
import structs.Vector3;

public class Rasterizer {

	private final static Vector2 offscreenP01 = new Vector2(-1, -1);
	private final static Vector2 offscreenP02 = new Vector2(-1, 100);

	/**
	 * Returns a vector3(alpha,beta,gamma) containing the barycentric
	 * coordinates of point p in the triangle constituted by points a,b and c.
	 * 
	 * @param p
	 * @param a
	 * @param b
	 * @param c
	 * @return
	 */
	@Deprecated
	public static Vector3 CalculateBarycentric2D(Vector2 p, Vector2 a, Vector2 b, Vector2 c) {
		float alpha = f(p, b, c) / f(a, b, c);
		float beta = f(p, c, a) / f(b, c, a);
		float gamma = f(p, a, b) / f(c, a, b);
		return new Vector3(alpha, beta, gamma);
	}

	/**
	 * Solves the implicit line equation.
	 * 
	 * @param p
	 * @param a
	 * @param b
	 * @return
	 */
	private static float f(Vector2 p, Vector2 a, Vector2 b) {
		return (a.Y - b.Y) * p.X + (b.X - a.X) * p.Y + a.X * b.Y - b.X * a.Y;
	}

	public static void DrawTriangle(RenderPanel canvas, Vector2 a, Vector2 b, Vector2 c) {

		float falpha = f(a, b, c);
		float fbeta = f(b, c, a);
		float fgamma = f(c, a, b);

		for (int x = 0; x < canvas.getWidth(); x++) {
			for (int y = 0; y < canvas.getHeight(); y++) {

				Vector2 p = new Vector2(x, y);

				float alpha = f(p, b, c) / falpha;
				float beta = f(p, c, a) / fbeta;
				float gamma = f(p, a, b) / fgamma;

				if (alpha >= 0 && beta >= 0 && gamma >= 0) {
					if ((alpha > 0 || falpha * f(offscreenP01, b, c) > 0 || falpha * f(offscreenP02, b, c) > 0)
							&& (beta > 0 || fbeta * f(offscreenP01, c, a) > 0 || fbeta * f(offscreenP02, c, a) > 0)
							&& (gamma > 0 || fgamma * f(offscreenP01, a, b) > 0 || fgamma * f(offscreenP01, a, b) > 0)) {

						Color red = Color.RED;
						Color green = Color.GREEN;
						Color blue = Color.BLUE;

						float re = alpha * red.getRed() + beta * green.getRed() + gamma * blue.getRed();
						float gr = alpha * red.getGreen() + beta * green.getGreen() + gamma * blue.getGreen();
						float bl = alpha * red.getBlue() + beta * green.getBlue() + gamma * blue.getBlue();

						Color rgb = new Color((int) (re + 0.5f), (int) (gr + 0.5f), (int) (bl + 0.5f));

						canvas.drawPixel(x, y, rgb);
					}
				}
			}
		}
	}

}
